三菱PLC通信(MC协议A

您所在的位置:网站首页 三菱 plc 协议 三菱PLC通信(MC协议A

三菱PLC通信(MC协议A

2023-11-04 18:30| 来源: 网络整理| 查看: 265

1、首先看一下网络模型

UDP协议是无连接,尽最大可能交付报文,没有拥塞控制,面向报文(不分割、不合并) 

TCP面向连接,提供可靠交付,有流量控制、拥塞控制,面向字节流(从上层传下的数据进行分割,分割成合适运输的数据块)只能是一对一连接。

 

2、三菱的PLC通信

在三菱的PLC通信的MC协议中,分为串行通信的报文和以太网接口的报文。 在串口通信中,共有以下几种帧,其中1C,2C,3C帧支持格式1,2,3,4,在C帧里支持格式5通信

4C帧,QnA系列串行通信模块专用协议(Qna扩展帧)3C帧,QnA系列串行通信模块专用协议(Qna帧)2C帧,QnA系列串行通信模块专用协议(Qna简易帧)1C帧,A系列计算机链接模块专用协议

在以太网通信中,共有以下几种帧,每种帧支持二进制和ASCII格式。A-1E为较早的通信版本,对地址的操作范围有限(数据寄存器区的D0~D6143、D9000~D9255),Qna-3E可访问D0~D12287数据

4E帧,是3E帧上附加了“序列号”。3E帧,QnA系列以太网接口模块的报文格式,兼容SLMP的报文格式1E帧,A系列以太网接口模块的报文格式

Demo利用MC协议的A-1E模式,使用ASCII进行通信,基本实现int、float、bit的单点及批量的读写测。试,及利用异步监视PLC某点值的变化,使用PLC 的脉冲模拟数据的变化。代码编写未使用OOP思想,后期需要进行代码的优化

1、MC协议帧,A-1E帧

1、读还是写,字还是位 

 

 

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; using Microsoft.VisualBasic; using Microsoft.CodeAnalysis.VisualBasic; using System.Threading; namespace MCFx { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //A-1E只能操作D0~D6143,D9000~D9255 groupBox1.Enabled = false; } private static TcpClient Client; private string IpAddress; private int PortNum; private static byte[] Buffer; //=new byte[256]; private byte[] InBuff = new byte[1532]; private static string TxCommand; private static string RxResponse; private static string Temp; private static int j; double[] Dreg = new double[65536]; //private double[] Dreg; private string DregStr; private string SubHeader; private int Muloffset; //PLC连接 private void ConPlc(string IpAddress, int PortNum) { IpAddress = IpAddress; PortNum = PortNum; Client = new TcpClient(); try { Client.Connect(IpAddress, PortNum); if (Client.Connected == true) { groupBox1.Enabled = true; txtError.Text = " Success Connection"; } else { MessageBox.Show("Connection Fail"); } } catch (Exception ex) { MessageBox.Show("Connection Fail,Next return code will be reback:{0}", ex.Message); } } //PLC断开连接 private void DisconPlc() { try { if (Client == null) { MessageBox.Show("Not Connection PLC "); txtError.Text = "Not Connection PLC "; } else { Client.GetStream().Close(); Client.Close(); if (Client.Connected == false) { txtError.Text = "Success DisConnection PLC"; } groupBox1.Enabled = false; } } catch (Exception e) { MessageBox.Show("Not Connection PLC "); } } private bool DataQuery(string offset, string num) { if (offset == "") { MessageBox.Show("Please input your offset"); return false; } else if (num == "") { MessageBox.Show("Please input your ElementNum"); return false; } else { return true; } } //连接PLC private void button7_Click(object sender, EventArgs e) { string IpAddress = txtIP.Text; int PortNum = int.Parse(txtPort.Text); ConPlc(IpAddress, PortNum); } //整型批量读 D区 private void button1_Click(object sender, EventArgs e) { double[] DregInt = new double[25536]; //使用A互换1E结构的命令,读出D0~D4(5个点) TxCommand = "01 FF 000A 4420 00000000 05 00"; //二进制通信,以字为单位成批读出 // 读字单位 PC号 ASCii 起始地址 个数 TxCommand = TxCommand.Replace(" ", ""); if (DataQuery(txtoffset.Text, txtFloatNum.Text) == true) { //读取int个数处理 int num = int.Parse(txtFloatNum.Text); //string HexNum = '0' + (num * 2).ToString(); string HexNum = string.Format("{0:X}", num); //大写对大写X x //122 HexNum = HexNum.ToString().PadLeft(2, '0'); //不够两个左边补0 TxCommand = TxCommand.Remove(20, 2); TxCommand = TxCommand.Insert(20, HexNum); //偏移量处理。比如从D1开始读 int offset = int.Parse(txtoffset.Text); string OffsetNum = string.Format("{0:X}", offset); //大写对大写X x //122 OffsetNum = OffsetNum.ToString().PadLeft(2, '0'); //不够两个左边补0 TxCommand = TxCommand.Remove(18, 2); TxCommand = TxCommand.Insert(18, OffsetNum); Buffer = System.Text.Encoding.Default.GetBytes(TxCommand.Trim().ToCharArray()); //发送命令 Client.GetStream().Write(Buffer, 0, Buffer.Length); //等待以太网适配器的响应 while (!Client.GetStream().DataAvailable) { Application.DoEvents(); } Client.GetStream().Read(InBuff, 0, InBuff.Length); RxResponse = System.Text.Encoding.Default.GetString(InBuff); SubHeader = RxResponse.Substring(2, 2);//开始的第三位取两个 if (SubHeader == "00") //正常响应 { //整型的16位批量处理 Temp = ""; //初始化输出字符 for (j = 0; j


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3